package com.songyuesheng.app.config;

import cn.hutool.core.util.StrUtil;
import com.songyuesheng.app.commom.ContextHolder;
import com.songyuesheng.app.util.JwtUtil;
import io.jsonwebtoken.ExpiredJwtException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class TokenInterceptor implements HandlerInterceptor {

    /**
     * 请求头
     */
    private static final String HEADER_AUTH = "Authorization";

    /**
     * 安全的url，不需要令牌
     */
    private static final List<String> SAFE_URL_LIST = Arrays.asList(
        "/login",
        "/register",
        "/refreshToken"
    );

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        response.setContentType("application/json; charset=utf-8");

        String url = request.getRequestURI().substring(request.getContextPath().length());
//        System.out.println(url);
        // 登录和注册等请求不需要令牌
        if (SAFE_URL_LIST.contains(url)) {
            return true;
        }

        // 从请求头里面读取token
        String token = request.getHeader(HEADER_AUTH);
        if (StrUtil.isBlank(token)) {
            token = request.getParameter("token");//url参数?token=xxx
            if (StrUtil.isBlank(token)) {
                throw new RuntimeException("请求失败,token为空,请登录");
            }
        }

        // 解析访问令牌
        try {
            // 确保正确处理token前缀
            if (token.startsWith(JwtUtil.TOKEN_PREFIX + "_")) {
                Map<String, Object> map = JwtUtil.resolveAccessToken(token);
                Long userId = ((Number) map.get("userId")).longValue();
                ContextHolder.setUserId(userId);
                return true;
            }
            throw new RuntimeException("token格式不正确，缺少Bearer前缀");
        } catch (ExpiredJwtException e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            throw new RuntimeException("访问令牌已过期");
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            throw new RuntimeException("访问令牌验证失败: " + e.getClass().getSimpleName() + ": " + e.getMessage());
        }
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ContextHolder.shutdown();
    }
}
